﻿using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Collections.Generic;
using System.Xml;

namespace XeoEngine
{
    class GraphicOptionsMenuScreen : MenuScreen
    {
        int currentmode;
        List<DisplayMode> dmList = new List<DisplayMode>();
        int oldwidth;
        int oldheight;
        bool oldvs;
        bool oldms;
        bool oldfs;
        MenuEntry resEntry;
        MenuEntry VSync;
        MenuEntry MulSampl;
        MenuEntry FullScreen;

        public GraphicOptionsMenuScreen(int reswidth, int resheight, bool VertSync, bool ms, bool fullscreen)
            : base(Localizations.Strings.Graphics)
        {
            oldwidth = reswidth;
            oldheight = resheight;
            oldvs = VertSync;
            oldms = ms;
            oldfs = fullscreen;
            oldwidth = reswidth;
            oldheight = resheight;
            oldvs = VertSync;
            oldms = ms;
            oldfs = fullscreen;
            resEntry = new MenuEntry(Localizations.Strings.Resolution + "   ");
            VSync = new MenuEntry(Localizations.Strings.VSync + "   " + (VertSync ? Localizations.Strings.On : Localizations.Strings.Off));
            MulSampl = new MenuEntry(Localizations.Strings.MultiSampling + "   " + (ms ? Localizations.Strings.On : Localizations.Strings.Off));
            FullScreen = new MenuEntry(Localizations.Strings.Windowed + "   " + (fullscreen ? Localizations.Strings.Off : Localizations.Strings.On));
            MenuEntry back = new MenuEntry(Localizations.Strings.Back);
            MenuEntry apply = new MenuEntry(Localizations.Strings.Apply);
            back.Selected += OnCancel;
            resEntry.Selected += ResolutionMenuEntrySelected;
            VSync.Selected += VSyncEntrySelected;
            MulSampl.Selected += MulSamplEntrySelected;
            FullScreen.Selected += FullScreenEntrySelected;
            apply.Selected += OnApply;
            MenuEntries.Add(resEntry);
            MenuEntries.Add(VSync);
            MenuEntries.Add(MulSampl);
            MenuEntries.Add(FullScreen);
            MenuEntries.Add(apply);
            MenuEntries.Add(back);
            resEntry.Text = Localizations.Strings.Resolution + "   " + System.String.Format("{0}x{1}", reswidth, resheight);
            foreach (DisplayMode dm in GraphicsAdapter.DefaultAdapter.SupportedDisplayModes)
            {
                dmList.Add(dm);
                if (dmList[dmList.Count - 1].Height == resheight && dmList[dmList.Count - 1].Width == reswidth)
                {
                    currentmode = dmList.Count - 1;
                }
            }
        }

        void ResolutionMenuEntrySelected(object sender, PlayerIndexEventArgs e)
        {
            currentmode++;
            if (currentmode >= dmList.Count) currentmode = 0;
            resEntry.Text = Localizations.Strings.Resolution + "   " + String.Format("{0}x{1}", dmList[currentmode].Width, dmList[currentmode].Height);
        }

        void VSyncEntrySelected(object sender, PlayerIndexEventArgs e)
        {
            ScreenManager.Graphics.SynchronizeWithVerticalRetrace = !ScreenManager.Graphics.SynchronizeWithVerticalRetrace;
            VSync.Text = Localizations.Strings.VSync + "   " + (ScreenManager.Graphics.SynchronizeWithVerticalRetrace ? Localizations.Strings.On : Localizations.Strings.Off);
        }

        void MulSamplEntrySelected(object sender, PlayerIndexEventArgs e)
        {
            ScreenManager.Graphics.PreferMultiSampling = !ScreenManager.Graphics.PreferMultiSampling;
            MulSampl.Text = Localizations.Strings.MultiSampling + "   " + (ScreenManager.Graphics.PreferMultiSampling ? Localizations.Strings.On : Localizations.Strings.Off);
        }

        void FullScreenEntrySelected(object sender, PlayerIndexEventArgs e)
        {
            ScreenManager.Graphics.IsFullScreen = !ScreenManager.Graphics.IsFullScreen;
            FullScreen.Text = Localizations.Strings.Windowed + "   " + (ScreenManager.Graphics.IsFullScreen ? Localizations.Strings.Off : Localizations.Strings.On);
        }

        void OnApply(object sender, PlayerIndexEventArgs e)
        {
            ScreenManager.Graphics.PreferredBackBufferWidth = dmList[currentmode].Width;
            ScreenManager.Graphics.PreferredBackBufferHeight = dmList[currentmode].Height;
            ScreenManager.Graphics.ApplyChanges();
            string message = Localizations.Strings.SaveScreenSettingsWarn;
            MessageBoxScreen confirmQuitMessageBox = new MessageBoxScreen(message, Localizations.Strings.Yes, Localizations.Strings.No);
            confirmQuitMessageBox.Accepted += ConfirmQuitMessageBoxAccepted;
            confirmQuitMessageBox.Cancelled += ConfirmQuitMessageBoxCancelled;
            confirmQuitMessageBox.TimeInCancelButton = 15;
            ScreenManager.AddScreen(confirmQuitMessageBox, ControllingPlayer);
        }

        void ConfirmQuitMessageBoxAccepted(object sender, PlayerIndexEventArgs e)
        {
            SaveSettings(ScreenManager);
            OnCancel(PlayerIndex.One);
        }

        public static void SaveSettings(ScreenManager sm)
        {
            using (XmlWriter writer = XmlWriter.Create("Content/Settings.xml"))
            {
                writer.WriteStartDocument();
                writer.WriteStartElement("Settings");
                writer.WriteStartElement("Graphics");
                writer.WriteStartElement("Resolution");
                writer.WriteStartElement("Width");
                writer.WriteValue(sm.Graphics.PreferredBackBufferWidth);
                writer.WriteEndElement();
                writer.WriteStartElement("Height");
                writer.WriteValue(sm.Graphics.PreferredBackBufferHeight);
                writer.WriteEndElement();
                writer.WriteEndElement();
                writer.WriteStartElement("VSync");
                writer.WriteString(sm.Graphics.SynchronizeWithVerticalRetrace.ToString());
                writer.WriteEndElement();
                writer.WriteStartElement("MultiSampling");
                writer.WriteString(sm.Graphics.PreferMultiSampling.ToString());
                writer.WriteEndElement();
                writer.WriteStartElement("FullScreen");
                writer.WriteString(sm.Graphics.IsFullScreen.ToString());
                writer.WriteEndElement();
                writer.WriteEndElement();
                writer.WriteStartElement("Interface");
                writer.WriteStartElement("Language");
                writer.WriteString(Localizations.Strings.Culture.IetfLanguageTag);
                writer.WriteEndElement();
                writer.WriteEndElement();
                writer.WriteStartElement("Sound");
                writer.WriteStartElement("MusicVol");
                writer.WriteValue(sm.smvol);
                writer.WriteEndElement();
                writer.WriteStartElement("MenuVol");
                writer.WriteValue(sm.mvol);
                writer.WriteEndElement();
                writer.WriteStartElement("SceneVol");
                writer.WriteValue(sm.svol);
                writer.WriteEndElement();
                writer.WriteEndElement();
                writer.WriteEndElement();
                writer.WriteEndDocument();
            }
        }
        
        void ConfirmQuitMessageBoxCancelled(object sender, PlayerIndexEventArgs e)
        {
            ScreenManager.Graphics.PreferredBackBufferWidth = oldwidth;
            ScreenManager.Graphics.PreferredBackBufferHeight = oldheight;
            ScreenManager.Graphics.PreferMultiSampling = oldms;
            ScreenManager.Graphics.IsFullScreen = oldfs;
            ScreenManager.Graphics.SynchronizeWithVerticalRetrace = oldvs;
            ScreenManager.Graphics.ApplyChanges();
        }
    }
}
